<?php

namespace app\api\model;

use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Element\Section;
use PhpOffice\PhpWord\Element\TextRun;
use PhpOffice\PhpWord\Style\Font;
use PhpOffice\PhpWord\Style\Paragraph;
use PhpOffice\PhpWord\Style\Table;

use PhpOffice\PhpWord\Element\Row;
use PhpOffice\PhpWord\Element\Cell;

include(ROOT_PATH.'extend/phplatex.php');

class Word
{

    public function printTable($ids,$topic,$answer)
    {
        $list = collection(Cuoti::where('id','in',$ids)->select())->toArray();
        /*$a = $this->texify("$$\begin{align}
         (a+b)^3 & = (a+b)^2(a+b)\\\\
                 & = (a^2+2ab+b^2(a+b)\\\\\
                 & = (a^3+2a^2b+ab^2) + (a^2b+2ab^2+b^3)\\\\\
                 & = a^3+3a^2b+3ab^2ab^2+b^3
       \\end{align}$$");
        dump($a);*/

        $phpWord = new PhpWord();
        // 添加标题
        $section = $phpWord->addSection();

        $section->addText('错题本大赢家,你的提分军师', ['bold' => true, 'size' => 10,'color'=>'#9faffc'], ['alignment' => 'right']);
        $section->addTextBreak(1);
        // 设置段落样式
        $paragraphStyle = new Paragraph();
        $paragraphStyle->setSpaceAfter(0);
        $paragraphStyle->setSpaceBefore(0);

        // 创建错题记录表格
        $tableStyle = new Table();
        $tableStyle->setBorderSize(0);
        $tableStyle->setBorderColor('#3c4e99');
        $tableStyle->setCellMargin(200); // 单元格内边距（微米）

        $table = $section->addTable($tableStyle);
        // 创建一个Font样式
        $fontStyle = new Font();
        $fontStyle->setUnderline(Font::UNDERLINE_SINGLE);

        $date = date('Y-m-d',time());
        // 添加错题记录
        foreach ($list as $index=>$value) {
            $row = $table->addRow();
            $num = $index+1;
            // 题目序号
            $cell1 = $row->addCell(5000);
            $cell1->addText("题目序号:{$num}", ['bold' => true,'size' => 10,'color'=>'#3c4e99'],$fontStyle);
            $cell1->addTextBreak(1);
            $cell1->addText("日期:{$date}", ['bold' => true,'size' => 10,'color'=>'#3c4e99']);
            $cell1->addTextBreak(1);
            $cell1->addText("来源:日常试卷", ['bold' => true,'size' => 10,'color'=>'#3c4e99']);
            $cell1->addTextBreak(1);
            $cell1->addText("重要程度:☆☆☆☆☆", ['bold' => true,'size' => 10,'color'=>'#3c4e99']);
            $cell1->addTextBreak(1);
            $cell1->addText("掌握程度:☆☆☆☆☆", ['bold' => true,'size' => 10,'color'=>'#3c4e99']);
            $cell1->addTextBreak(1);
            $cell1->addText("原因分析", ['bold' => true,'size' => 15,'color'=>'#3c4e99']);
            $cell1->addTextBreak(1);
            $cell1->addText("拼写错误 ○    语法错误 ○", ['size' => 10,'color'=>'#abb1c8']);
            $cell1->addTextBreak(1);
            $cell1->addText("用词错误 ○    理解错误 ○", ['size' => 10,'color'=>'#abb1c8']);
            $cell1->addTextBreak(1);
            $cell1->addText("审题不清 ○    时间不足 ○", ['size' => 10,'color'=>'#abb1c8']);
            $cell1->addTextBreak(1);
            $cell1->addText("其他原因:", ['size' => 10,'color'=>'#abb1c8']);
            $cell1->addTextBreak(2);
            //$cell1->setBorderBottom(Table:: BORDER_SINGLE, 1, '#000000');
            $title = htmlspecialchars($value['title']);

            // 原题内容
            $cell2 = $row->addCell(9000);
            $cell2->addText("原题:                    ○好题    ○难题    ○常考题", ['bold' => true, 'size' => 10,'color'=>'#3c4e99']);
            $cell2->addTextBreak();
            if ($title&&$topic==1){
                if ($value['image']){
                    $imagePath = ROOT_PATH.'public'.$value['image']; // 确保图片路径正确
                    //dump($imagePath);die;

                    if (file_exists($imagePath)) {
                        $image = $cell2->addImage($imagePath, [
                            'width' => 280,
                            'height' => 130
                        ]);
                    } else {
                        $section->addText('图片文件不存在。');
                    }
                }
                //$cell2->addText($title, ['size' => 10,'color'=>'#3c4e99','italic' => true],'html');
            }
            /*if ($title&&$topic==1){
                $cell2->addText($title, ['size' => 10,'color'=>'#3c4e99','italic' => true],'html');
            } else {
                if ($value['image']){
                    $imagePath = ROOT_PATH.'public'.$value['image']; // 确保图片路径正确
                    //dump($imagePath);die;

                    if (file_exists($imagePath)) {
                        $image = $cell2->addImage($imagePath, [
                            'width' => 100,
                            'height' => 50
                        ]);
                    } else {
                        $section->addText('图片文件不存在。');
                    }
                }
            }*/




            //dump($content);die;
            $cell2->addTextBreak(1);
            $cell2->addText("原题&分析：", ['bold' => true,'size' => 10,'color'=>'#3c4e99']);
            $cell2->addTextBreak(1);
            if ($value['answer']&&$answer==1){
                preg_match_all('/\\\\([()])(.*?)\\\\([()])/', $value['answer'], $matches);
                foreach ($matches[2] as $formula) {
                    $latex = convertToLatex($formula);
                    $cell2->addText($latex, ['math' => true,'size' => 10,'color'=>'#3c4e99'],'html');
                }
                //$cell2->addText($value['answer'], ['size' => 10,'color'=>'#3c4e99'],'html');
            }

            //$cell3 = $row->addCell(2000);
            //$cell3->addText('-------------', ['size' => 10,'color'=>'#3c4e99']);
            //$cell3->addText($value['answer'], ['size' => 10,'color'=>'#3c4e99']);
          /*  // 日期
            $cell3 = $row->addCell(2000);
            $cell3->addText('2023-10-01', ['align' => 'right', 'size' => 10]);
            //$cell3->setBorderBottom(Table:: BORDER_SINGLE, 1, '#000000');

            // 来源
            $cell4 = $row->addCell(2000);
            $cell4->addText('考试A', ['align' => 'right', 'size' => 10]);
            //$cell4->setBorderBottom(Table:: BORDER_SINGLE, 1, '#000000');

            // 掌握程度
            $cell5 = $row->addCell(2000);
            $cell5->addText('★★★', ['align' => 'right', 'size' => 10]);*/
            //$cell5->setBorderBottom(Table:: BORDER_SINGLE, 1, '#000000');
        }

        // 设置文件名和路径
        $filePath = $this->getDocumentPath();
        $fileName = $this->getUniqueFileName();

        // 设置响应头
       /* header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
        header('Content-Disposition: attachment;filename="导出文档.docx"');
        header('Cache-Control: max-age=0');*/

        // 输出Word文档
        $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
        $objWriter->save($filePath . $fileName);

        // 获取带域名的完整路径
        $fullPath = $this->getFullPath($fileName);

        return $fullPath;
    }

    public function print($ids,$subject,$topic,$answer)
    {
        $cuoti_model = new Cuoti();
        $subject_list = $cuoti_model->getSubjectList();
        $list = Cuoti::where('id','in',$ids)->select();

        if ($topic){
            $tail = '题目';
        } else {
            $tail = '答案';
        }

        $title = "我的{$subject_list[$subject]}错题复习卷({$tail})";


        // 设置文件名和路径
        $filePath = $this->getDocumentPath();
        $fileName = $this->getUniqueFileName();

        $phpWord = new PhpWord();
        // 添加一个页面
        $section = $phpWord->addSection();
        $paragraphStyle = array(
            'align' => 'center',
            'spaceBefore' => 600, // 段前间距，以缇为单位
            'spaceAfter' => 600 // 段后间距，以缇为单位
        );
        // 添加标题
        $section->addText($title, array('name' => 'Arial', 'size' => 16, 'bold' => true,'color'=>'#627af6'),$paragraphStyle);

        $section->addText(date('Y-m-d',time()), array('name' => 'Arial', 'size' => 10, 'bold' => true,'color'=>'#627af6'),$paragraphStyle);

        foreach ($list as $k=>$v){
            $num = $k+1;
            // 添加一些内容
            if ($topic){
                $section->addText($num.'.'.$v['title']);
            }

            if ($v['image']){
                $imagePath = ROOT_PATH.'public'.$v['image']; // 确保图片路径正确
                //dump($imagePath);die;

                if (file_exists($imagePath)) {
                    $image = $section->addImage($imagePath, [
                        'width' => 100,
                        'height' => 50
                    ]);
                } else {
                    $section->addText('图片文件不存在。');
                }
            }

            if ($answer){
                $section->addText($v['answer']);
                if ($v['answer_img']){
                    $imagePath = ROOT_PATH.'public'.$v['answer_img']; // 确保图片路径正确
                    //dump($imagePath);die;

                    if (file_exists($imagePath)) {
                        $image = $section->addImage($imagePath, [
                            'width' => 100,
                            'height' => 50
                        ]);
                    } else {
                        $section->addText('图片文件不存在。');
                    }
                }
            }
            $section->addTextBreak(2);
        }

        // 设置响应头
       /* header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
        header('Content-Disposition: attachment;filename="导出文档.docx"');
        header('Cache-Control: max-age=0');*/

        // 输出Word文档
        $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');

        $objWriter->save($filePath . $fileName);

        // 获取带域名的完整路径
        $fullPath = $this->getFullPath($fileName);

        return $fullPath;
    }

    /**
     * 获取文档保存路径
     * @return string
     */
    private function getDocumentPath()
    {
        $date = date('Y-m-d');
        $path = ROOT_PATH . 'public/word/' . $date . '/';

        // 确保目录存在，不存在则创建
        if (!is_dir($path)) {
            mkdir($path, 0755, true);
        }

        return $path;
    }

    /**
     * 生成唯一的文件名
     * @return string
     */
    private function getUniqueFileName()
    {
        // 使用日期和时间戳生成唯一文件名
        $fileName = date('Y-m-d_H-i-s') . '_' . uniqid() . '.docx';

        return $fileName;
    }

    /**
     * 获取带域名的完整路径
     * @param string $fileName 文件名
     * @return string
     */
    private function getFullPath($fileName)
    {
        $date = date('Y-m-d');
        $fullPath = 'https://' . $_SERVER['HTTP_HOST'] . '/word/' . $date . '/' . $fileName;

        return $fullPath;
    }


    public $path_to_latex   = '/usr/bin/latex';
    public $path_to_dvips   = '/usr/bin/dvips';
    public $path_to_convert = '/usr/bin/convert';

    public $imgfmt="png"; # used in extensions, and in parameters to convert. Should be either png or gif.


    public function phplatex_cleantmp($tempfname,$todir) {
        # removes the various files that probably got created for a specific run, based on the run's filename.
        //global $imgfmt;
        if (chdir($todir)===FALSE) { return '[directory access error, fix permissions (and empty tmp manually this time)]'; }
        error_reporting(0); #at least one of these probably will not exist, but disable the error reporting related to that.
        unlink($tempfname);     #the longer/cleaner way would be check for existance for each
        unlink($tempfname.".tex");  unlink($tempfname.".log");
        unlink($tempfname.".aux");  unlink($tempfname.".dvi");
        unlink($tempfname.".ps");   unlink($tempfname.".".$this->imgfmt);
        error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
        #try-catch would have been nice. This is rather overkill too, the way I use it.
        return '';
    }

    public function phplatex_colorhex($r,$g,$b) {
        #there has to be a better way of doing this. It's not even particularly clean.
        $hex=array("","","");
        if(strlen($hex[0]=dechex(min(255*$r,255)))==1){ $hex[0]="0".$hex[0]; }
        if(strlen($hex[1]=dechex(min(255*$g,255)))==1){ $hex[1]="0".$hex[1]; }
        if(strlen($hex[2]=dechex(min(255*$b,255)))==1){ $hex[2]="0".$hex[2]; }
        return implode("",$hex);
    }


    public function texify($string,$dpi='90', $r=0.0,$g=0.0,$b=0.0, $br=1.0,$bg=1.0,$bb=1.0,$extraprelude="", $trans=FALSE) {
        //global $imgfmt,$path_to_latex,$path_to_dvips,$path_to_convert;
        if ($dpi>300) $dpi=300;

        $back = phplatex_colorhex($br,$bg,$bb);
        $fore = phplatex_colorhex($r,$g,$b);

        # Figure out TeX string, either to get the right cache entry, or to compile
        # Adds semi-common symbol packages (ams)
        # used to include ,landscape in documentclass to avoid page wrapping, but it seems this sometimes implies 90 degree rotation
        $totex = "\\documentclass[14pt]{extarticle}\n".
            "\\usepackage{color}\n".
            "\\usepackage{amsmath}\n\\usepackage{amsfonts}\n\\usepackage{amssymb}\n".
            $extraprelude."\n".
            "\\pagestyle{empty}\n".  #removes header/footer; necessary for trim
            "\\begin{document}\n".
            "\\color[rgb]{".$r.",".$g.",".$b."}\n".
            "\\pagecolor[rgb]{".$br.",".$bg.",".$bb."}\n".
            $string."\n".
            "\\end{document}\n";
        $hashfn = sha1($totex).".".$dpi.".".$fore.".".$back.".".intval($trans);  #file cache entry string:  40-char hash string plus size
        $stralt = str_replace("&","&amp;", preg_replace("/[\"\n]/","",$string)); # stuck in the alt and title attributes
        # May need some extra safety.
        $heredir = getcwd();

        # Experiment: Tries to adjust vertical positioning, so that rendered TeX text looks natural enough inline with HTML text
        #  Only descenders are really a problem since HTML's leeway is upwards.
        #  Some things vary per font, e.g. the slash. In the default CM it is a descender, in Times and others it isn't.
        #  TODO: This can always use more work.
        #  TODO: Avoid using characters that are part of TeX commands.
        $ascenders ="/(b|d|f|h|i|j|k|l|t|A|B|C|D|E|F|G|H|I|J|L|K|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|\[|\]|\\{|\\}|\(|\)|\/|0|1|2|3|4|5|6|7|8|9|\\#|\*|\?|'|\\\\'|\\\\`|\\\\v)/";
        $monoliners="/(a|c|e|m|n|o|r|s|u|v|w|x|z|-|=|\+|:|.)/";
        $descenders="/(g|j|p|\/|q|y|Q|,|;|\[|\]|\\{|\\}|\(|\)|\#|\\\\LaTeX|\\\\TeX|\\\\c\{)/";
        $deepdescenders="/(\[|\]|\\{|\\}|\(|\)|\\int)/";

        $ba = preg_match_all($ascenders,  $string,$m);
        $bm = preg_match_all($monoliners, $string,$m);
        $bd = preg_match_all($descenders, $string,$m);
        $dd = preg_match_all($deepdescenders, $string,$m);
        if      ($dd>0)            $verticalalign="vertical-align: -25%";   # deep descenders: move down
        else if ($bd>0 && $ba==0)  $verticalalign="vertical-align: -15%";   # descenders:  move down
        else if ($bd==0 && $ba>0)  $verticalalign="vertical-align: 0%";     # ascenders only: move up/do nothing?
        else if ($bd==0 && $ba==0) $verticalalign="vertical-align: 0%";     # neither    vertical-align: 0%
        else                       $verticalalign="vertical-align: -15%";   # both ascender and regular descender


        # check if image for that TeX in the cache, return img HTML if it exists
        if (file_exists($heredir.'/images/'.$hashfn.'.'.$this->imgfmt))
            return '<img style="'.$verticalalign.'" title="'.$stralt.'" alt="'.$stralt.'" src="images/'.$hashfn.'.'.$this->imgfmt.'">';

        # otherwise try to make and store:

        # chdir to have superfluous files be created in just one place, tmp/  (you probably want to occasionally clean this yourself)
        error_reporting(0); # TODO: fetch current value so we can restore it
        if (chdir("tmp")===FALSE) { return '[tmp directory access error, please fix permissions]'; } #I should think about some more specific errors, e.g. check whether file creation is allowed
        error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);

        $tfn = tempnam(getcwd(), 'PTX'); # unique base path in tmp dir

        #write temporary .tex file
        if ( ($tex = fopen($tfn.'.tex', "w"))==FALSE) { return '[tex file access error] '.phplatex_cleantmp($tfn,$heredir); }
        fwrite($tex, $totex);
        fclose($tex);


        # Run latex to create a .dvi.  Have it try to fix minor errors instead of breaking/pausing on them.
        exec($this->path_to_latex.' --interaction=nonstopmode '.$tfn.'.tex');
        if (!file_exists($tfn.".dvi")) {
            $log = file_get_contents($tfn.'.log'); #The log always exists, but now it's actually interesting since it'll contain an error
            return '[latex error, code follows]<pre>'.$totex.'</pre><p><b>Log file:</b><pre>'.$log.'</pre></p> '.phplatex_cleantmp($tfn,$heredir);
        }


        # DVI -> PostScript.   Since dvips uses lpr, which may be configured to actually print by default, force writing to a file with -o
        exec($this->path_to_dvips.' '.$tfn.'.dvi -o '.$tfn.'.ps');
        if ( !file_exists($tfn.'.ps'))  {
            return '[dvi2ps error] '.phplatex_cleantmp($tfn,$heredir);
        }


        # PostScript -> image.  Also trim based on corner pixel and set transparent color.
        $convert_cmd = $this->path_to_convert;
        if ($trans) {
            $convert_cmd .= ' -transparent-color "#'.$back.'" -transparent "#'.$back.'"';
        }
        $convert_cmd .= ' -colorspace RGB -density '.$dpi.' -trim +page '.$tfn.'.ps '.$tfn.'.'.$this->imgfmt;

        exec($convert_cmd);
        #Note: +page OR -page +0+0 OR +repage moves the image to the cropped area (kills offset)
        #Older code tried: exec('/usr/bin/mogrify -density 90 -trim +page -format $imgfmt '.$tfn.'.ps');
        # It seems some versions of convert may not have -trim. Old versions?

        if (!file_exists($tfn.'.'.$this->imgfmt))  {
            return '[image convert error] '.phplatex_cleantmp($tfn,$heredir);
        }

        # Copy result image to chache.
        copy($tfn.'.'.$this->imgfmt, $heredir.'/images/'.$hashfn.'.'.$this->imgfmt);

        # Clean up temporary files, and return link to just-created image
        return phplatex_cleantmp($tfn,$heredir).'<img style="'.$verticalalign.'" title="'.$stralt.'" alt="LaTeX formula: '.$stralt.'" src="images/'.$hashfn.'.'.$this->imgfmt.'">';
    }
}